﻿using System.Reflection.Emit;

namespace BorgExt.DynamicProxy
{
    internal static class ILGeneratorEx
    {
        public static void EmitLoadArg(this ILGenerator generator, int argIndex)
        {
            switch (argIndex)
            {
                case 0:
                    generator.Emit(OpCodes.Ldarg_0);
                    break;

                case 1:
                    generator.Emit(OpCodes.Ldarg_1);
                    break;

                case 2:
                    generator.Emit(OpCodes.Ldarg_2);
                    break;

                case 3:
                    generator.Emit(OpCodes.Ldarg_3);
                    break;

                default:
                    generator.Emit(OpCodes.Ldarg, argIndex);
                    break;
            }
        }

        public static void EmitLoadConst(this ILGenerator generator, int constValue)
        {
            switch (constValue)
            {
                case -1:
                    generator.Emit(OpCodes.Ldc_I4_M1);
                    break;

                case 0:
                    generator.Emit(OpCodes.Ldc_I4_0);
                    break;

                case 1:
                    generator.Emit(OpCodes.Ldc_I4_1);
                    break;

                case 2:
                    generator.Emit(OpCodes.Ldc_I4_2);
                    break;

                case 3:
                    generator.Emit(OpCodes.Ldc_I4_3);
                    break;

                case 4:
                    generator.Emit(OpCodes.Ldc_I4_4);
                    break;

                case 5:
                    generator.Emit(OpCodes.Ldc_I4_5);
                    break;

                case 6:
                    generator.Emit(OpCodes.Ldc_I4_6);
                    break;

                case 7:
                    generator.Emit(OpCodes.Ldc_I4_7);
                    break;

                case 8:
                    generator.Emit(OpCodes.Ldc_I4_8);
                    break;

                default:
                    generator.Emit(OpCodes.Ldc_I4, constValue);
                    break;
            }
        }

        public static void EmitLoadLocal(this ILGenerator generator, int localIndex)
        {
            switch (localIndex)
            {
                case 0:
                    generator.Emit(OpCodes.Ldloc_0);
                    break;

                case 1:
                    generator.Emit(OpCodes.Ldloc_1);
                    break;

                case 2:
                    generator.Emit(OpCodes.Ldloc_2);
                    break;

                case 3:
                    generator.Emit(OpCodes.Ldloc_3);
                    break;

                default:
                    generator.Emit(OpCodes.Ldloc, localIndex);
                    break;
            }
        }

        public static void EmitStoreLocal(this ILGenerator generator, int localIndex)
        {
            switch (localIndex)
            {
                case 0:
                    generator.Emit(OpCodes.Stloc_0);
                    break;

                case 1:
                    generator.Emit(OpCodes.Stloc_1);
                    break;

                case 2:
                    generator.Emit(OpCodes.Stloc_2);
                    break;

                case 3:
                    generator.Emit(OpCodes.Stloc_3);
                    break;

                default:
                    generator.Emit(OpCodes.Stloc, localIndex);
                    break;
            }
        }
    }
}

